package com.xtaller.easy.admin.config;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.xtaller.common.bean.JWTResult;
import com.xtaller.common.convert.J;
import com.xtaller.common.kit.JwtKit;
import com.xtaller.easy.admin.async.CacheSysTask;
import com.xtaller.easy.admin.model.SysLog;
import com.xtaller.easy.admin.tps.NetKit;

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import org.springframework.web.servlet.HandlerMapping;

import javax.servlet.http.HttpServletRequest;
import java.util.Map;

/**
 * Created by Taller on 2018/5/11
 */
@Aspect
@Component
public class HttpLogAspect {
    @Autowired
    @Lazy
    private CacheSysTask cacheSysTask;

    ThreadLocal<Long> startTime = new ThreadLocal<Long>();
    ThreadLocal<JSONObject> tem = new ThreadLocal<JSONObject>();

    // 接入
    @Pointcut("execution(public * com.xtaller.easy.admin.controller..*.*(..))")
    public void httpLog(){}

    @Before("httpLog()")
    public void doBefore(JoinPoint joinPoint) {
        startTime.set(System.currentTimeMillis());
        // 接收到请求，记录请求内容
        ServletRequestAttributes attributes = (ServletRequestAttributes)
                RequestContextHolder.getRequestAttributes();
        HttpServletRequest request = attributes.getRequest();
        String classMethod = joinPoint.getSignature().getDeclaringTypeName() + "." +joinPoint.getSignature().getName();
        classMethod = classMethod.replace("com.xtaller.easy.admin.controller.", "");

        JSONObject object = NetKit.getClientInfo(request);
        object.put("classMethod", classMethod);
        String params = "";
        if ("DELETE".equals(object.getString("method")) || "POST".equals(object.getString("method")) || "PUT".equals(object.getString("method"))) {
            Object[] paramsArray = joinPoint.getArgs();
            params = argsArrayToString(paramsArray);
            if(object.getString("url").indexOf("/common/login") > 0){
                object.put("type", 3);
            }else{
                object.put("type", 1);
            }
        } else {
            Map<?, ?> paramsMap = (Map<?, ?>) request.getAttribute(HandlerMapping.URI_TEMPLATE_VARIABLES_ATTRIBUTE);
            params = paramsMap.toString();
        }
        object.put("param", params);
        tem.set(object);
    }

    // 操作成功
    @AfterReturning(returning = "ret", pointcut = "httpLog()")
    public void doAfterReturning(Object ret) {
        JSONObject object = tem.get();
        object.put("error", 0);
        object.put("time", (System.currentTimeMillis() - startTime.get()));
        JSONObject result = J.o2j(ret);

        JSONObject body = J.o2j(result.get("body"));
        // object.put("result", body.get("result"));
        object.put("message", body.get("message") == null ? "" : body.get("message"));

        if(result.getInteger("statusCodeValue") == 200){
            object.put("error", 0);
        }else{
            object.put("error", 1);
        }
        String url = object.getString("url");
        if(url.indexOf("/common/login") > 0){
            String userId = "0";
            try {
                JSONObject r = J.o2j(body.get("result"));
                String token = r.getString("token");
                JWTResult jwt = JwtKit.validateJWT(token);
                userId = jwt.getClaims().getId();
                object.put("userId", userId);
                object.put("type", 3);
                object.put("token", token);
                object.put("creator", userId);
            }catch (Exception ex){

            }
        }

        if(!(url.indexOf("/sys/log") > 0)){
            SysLog log = J.o2m(object, SysLog.class);
            cacheSysTask.cacheLog(log);
        }
    }

    // 后置异常通知
    @AfterThrowing("httpLog()")
    public void throwss(JoinPoint jp){
        JSONObject object = tem.get();
        object.put("error", 9);
        object.put("time", (System.currentTimeMillis() - startTime.get()));
        SysLog log = J.o2m(object, SysLog.class);
        cacheSysTask.cacheLog(log);
    }

    private String argsArrayToString(Object[] paramsArray) {
        String params = "";
        if (paramsArray != null && paramsArray.length > 0) {
            for (int i = 0; i < 1; i++) {
                Object jsonObj = JSON.toJSON(paramsArray[i]);
                params += jsonObj.toString() + " ";
            }
        }
        return params.trim();
    }

}
